package model.action.basic_function_action;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;

import model.dap.dao.BusinessDAO;
import model.dap.domain.Business;
import model.dap.mapper.BusinessMapper;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import model.dap.dao.MailConfigDAO;
import model.dap.domain.MailConfig;
import model.dap.mapper.MailConfigMapper;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ModelDriven;
import common.base.BaseAction;
import common.util.EmailValidator;
import common.util.ValidateUtil;

//import javax.mail.SendFailedException;
@Results({
		@Result(name = "error", type = "tiles", location = "tiles.BusinessRegister"),
		@Result(name = "success", type = "tiles", location = "tiles.BusinessRegister"),
		@Result(name = "successex", type = "redirectAction", location = "Register_Business.html")
		})
@ParentPackage("master_tiles")
public class RegisterBusinessAction extends BaseAction implements
		ModelDriven<Business> {
	protected static Logger log = Logger.getLogger(RegisterBusinessAction.class);
	private static final long serialVersionUID = 1L;
	private Business business = new Business();
	//======================================================================================================

	private static int errTimes=0;
	private String to;
	private int typeID;
	private static EmailValidator emv = new EmailValidator();
	
	public static int getErrTimes() {
		return errTimes;
	}

	public static void setErrTimes(int errTimes) {
		RegisterBusinessAction.errTimes = errTimes;
	}

	public String getTo() {
		return to;
	}

	public void setTo(String to) {
		this.to = to;
	}

	public int getTypeID() {
		return typeID;
	}

	public void setTypeID(int typeID) {
		this.typeID = typeID;
	}
	
	public Business getUser() {
		return business;
	}

	public void setUser(Business business) {
		this.business = business;
	}
	
	// --- Bien cua mail------
	private static MailConfig mailConfig = new MailConfig();
	
	static Properties properties = new Properties();

	public static MailConfig getMailConfig() {
		return mailConfig;
	}

	public static void setMailConfig(MailConfig mailConfig) {
		RegisterBusinessAction.mailConfig = mailConfig;
	}

	public static Properties getProperties() {
		return properties;
	}

	public static void setProperties(Properties properties) {
		RegisterBusinessAction.properties = properties;
	}

	//======================================================================================================
	// REGISTER BUSINESS
	private String password, confirmPassword; 
	@Action("/master/insert-business")
	public String insertBusiness() {
		try {
			String type = ServletActionContext.getRequest().getMethod();
			
			if(type.toUpperCase() == "GET")
			{
				return "successex";
			}
			
			getCityList2();
			getCityList();
			loadParentDealCategory();
			getDistrictList(Integer.parseInt(getCitySelected()));
			
			 password = business.getPassWord();
			 confirmPassword = business.getConfirmPassword();
			 
			try 
	        { 
				if (ValidateUtil.validateEmptyString(password) == false &&
						ValidateUtil.validateEmptyString(confirmPassword) == false) 
				{
					business.setPassWord(ValidateUtil.MD5Encryption(business.getPassWord()));
					business.setConfirmPassword(ValidateUtil.MD5Encryption(business.getConfirmPassword()));
				}
			} 
	     
	        catch (NoSuchAlgorithmException a) 
	        { 
	            a.printStackTrace();
	        } 
	     
	        catch (UnsupportedEncodingException a) 
	        { 
	           a.printStackTrace();
	        }
			
			if (validateInputField() == false) {
				return ERROR;
			}
			business.setCityID(Integer.parseInt(getCitySelected()));
			business.setDistrictID(Integer.parseInt(getDistrictSelected()));
			BusinessMapper userMapper = new BusinessDAO();
			int userResult = userMapper.insertBusiness(business);
		
			if (userResult == 0) {
				showError("Lỗi trong quá trình tạo mới tài khoản doanh nghiệp. Vui lòng thử lại");
				return ERROR;
			}
			setSuccessmessage(getText("Đăng kí tài khoản doanh nghiệp thành công. Vui lòng kiểm tra email để xác nhận thông tin"));
			//SEND EMAIL
			execute(business.getEmail(), 1);
			return SUCCESS;
		} catch (Exception e) {
			log.error(e.getMessage());
			return ERROR;
		}
	}
	
	//======================================================================================================
	// SHOW DISTRICT LIST WHEN CHOOSE CITY
	@Action("/master/change-city")
	public String change_city() {
		try {
			String type = ServletActionContext.getRequest().getMethod();
			
			if(type.toUpperCase() == "GET")
			{
				return "successex";
			}

			getCityList2();
			loadParentDealCategory();
			getCityList();
			getDistrictList(Integer.parseInt(getCitySelected()));
			return ERROR;
			
		} catch (Exception e) {
			log.error(e.getMessage());
			return ERROR;
		}
	}
	
	
	//======================================================================================================
	// VALIDATE INPUT FIELD
	/**
	 * Validate input input form return message, true or false
	 */
	public boolean validateInputField() {
		boolean check = true;
		//=====================================================Validate EMPTY
		if (ValidateUtil.validateEmptyString(business.getEmail()) == true) {
			showError("Email không được để trống");
			check = false;
		}

		if (ValidateUtil.validateEmptyString(business.getFullName()) == true) {
			showError("Họ tên không được để trống");
			check = false;
		}

		if (ValidateUtil.validateEmptyString(business.getUserID()) == true) {
			showError("Tên tài khoản không được để trống");
			check = false;
		}

		if (ValidateUtil.validateEmptyString(password) == true) {
			showError("Mật khẩu không được để trống");
			check = false;
		}

		if (ValidateUtil.validateEmptyString(confirmPassword) == true) {
			showError("Mật khẩu xác nhận không được để trống");
			check = false;
		}
		if (ValidateUtil.validateEmptyString(business.getAddress()) == true) {
			showError("Địa chỉ không được để trống");
			check = false;
		}
		if (ValidateUtil.validateEmptyString(business.getPhoneNumber()) == true) {
			showError("Số điện thoại không được để trống");
			check = false;
		}
		if (ValidateUtil.validateEmptyString(business.getCompanyName()) == true) {
			showError("Tên công ty không được để trống");
			check = false;
		}
		if (ValidateUtil.validateEmptyString(business.getWebsite()) == true) {
			showError("Website không được để trống");
			check = false;
		}
		if (ValidateUtil.validateEmptyString(business.getTaxID()) == true) {
			showError("Mã số thuế không được để trống");
			check = false;
		}
		if (ValidateUtil.validateEmptyString(business.getBusinessDomain()) == true) {
			showError("Loại hình kinh doanh không được để trống");
			check = false;
		}
		
		//=====================================================Validate LENGTH
		if (ValidateUtil.validateLengthOfPassword(password) == false) {
			showError("Chiều dài mật khẩu từ 6 đến 50 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfFullname(business.getFullName()) == false) {
			showError("Chiều dài Họ tên phải từ 6 đến 50 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfAddress(business.getAddress()) == false) {
			showError("Chiều dài địa chỉ phải từ 10 đến 100 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfPhoneNumber(business.getPhoneNumber()) == false) {
			showError("Chiều dài số điện thoại phải từ 10 đến 20 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfUserID(business.getUserID()) == false) {
			showError("Chiều dài tên đăng nhập từ 6 đến 25 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfCompanyName(business.getCompanyName()) == false) {
			showError("Chiều dài tên công ty phải từ 6-200 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfTaxID(business.getTaxID()) == false) {
			showError("Chiều dài mã số thuế phải từ 6-15 kí tự");
			check = false;
		}

		if (ValidateUtil.validateLengthOfBusinessDomain(business
				.getBusinessDomain()) == false) {
			showError("Chiều dài loại hình kinh doanh phải từ 6-50 kí tự");
			check = false;
		}
		//=====================================================Validate STANDARD
		if (emv.validate(business.getEmail()) == false) {
			showError("Email không hợp lệ");
			check = false;
		}

		if (ValidateUtil.validateConfirmPassword(password,
				confirmPassword) == false) {
			showError("Mật khẩu và xác nhận mật khẩu không đúng");
			check = false;
		}

		if (ValidateUtil.validateNameStandard(business.getUserID()) == false) {
			showError("Tên tài khoản chỉ được chứa các kí tự a-z, A-Z, 0-9");
			check = false;
		}

		if (ValidateUtil.validateNameStandard(business.getCompanyName()) == false) {
			showError("Tên công ty chỉ được chứa các kí tự a-z, A-Z, 0-9");
			check = false;
		}

		if (ValidateUtil.validateNameStandard(business.getBusinessDomain()) == false) {
			showError("Loại hình kinh doanh chỉ được chứa các kí tự a-z, A-Z, 0-9");
			check = false;
		}
		
		if (ValidateUtil.validateNameStandard(business.getTaxID()) == false) {
			showError("Mã số thuế chỉ được chứa các kí tự a-z, A-Z, 0-9");
			check = false;
		}
		//=====================================================Validate EXIST
		if (ValidateUtil.validateBusinessExist(business.getUserID()) == false) {
			showError("Tài khoản này đã tồn tại");
			check = false;
		}

		if (ValidateUtil.validateBusinessEmailExist(business.getEmail()) == false) {
			showError("Email này đã tồn tại");
			check = false;
		}
		//====================================================VALIDATE NOT CHOOSE CITY, DISTRICT
		if(Integer.parseInt(getCitySelected())==0){
			showError("Thành phố không được để trống.");
			check = false;
		}
		
		if(Integer.parseInt(getDistrictSelected())==0){
			showError("Quận/huyện không được để trống.");
			check = false;
		}
		
		return check;
	}
	
	//======================================================================================================
	// GET MODEL FRO BUSINESS
	// ---------------SEND MAIL
	public void execute(String sTo, int sTypeID) throws IOException {     
		setTo(sTo);
		setTypeID(sTypeID);
		
		MailConfigMapper mailConfigMapper = new MailConfigDAO();
		mailConfig = mailConfigMapper.selectMailConfigByID(typeID);
		
		properties.put("mail.smtp.host", mailConfig.getSmtpHost());
		String socketPort=(" "+mailConfig.getSmtpSocketPort()).trim();
		String socketClass=(" "+mailConfig.getSmtpSocketClass()).trim();
		
		if(ValidateUtil.validateEmptyString(socketPort)==false&&ValidateUtil.validateEmptyString(socketClass)==false){
			properties.put("mail.smtp.socketFactory.port", mailConfig.getSmtpSocketPort());
			properties.put("mail.smtp.socketFactory.class",	mailConfig.getSmtpSocketClass());
		}
		properties.put("mail.smtp.auth", mailConfig.getSmtpAuth());
		properties.put("mail.smtp.port", mailConfig.getSmtpPort());
		properties.put("mail.smtp.password", mailConfig.getPassword());
        
		try {
			if(ValidateUtil.validateEmptyString(socketPort)==false&&ValidateUtil.validateEmptyString(socketClass)==false){
				Session session = Session.getDefaultInstance(properties,
						new javax.mail.Authenticator() {
							protected PasswordAuthentication getPasswordAuthentication() {
								return new PasswordAuthentication(mailConfig.getFrom(), mailConfig.getPassword());
							}
						});
				// encording utf8 - subject
				byte[] pSubject = mailConfig.getSubject().getBytes("UTF-8");
				String subjectValue = new String(pSubject, "UTF-8");
				// encording utf8 - subject
				String iBody=mailConfig.getBody()+" Tên tài khoản: "+business.getUserID()+" - Mật khẩu: "+password+" ";
				byte[] pBody = iBody.getBytes("UTF-8");
				String bodyValue = new String(pBody, "UTF-8");
				
				Message message = new MimeMessage(session);
				message.setFrom(new InternetAddress(mailConfig.getFrom()));
				message.setRecipients(Message.RecipientType.TO,
						InternetAddress.parse(to));
				message.setSubject(subjectValue);
				message.setText(bodyValue);
				Transport.send(message);
				
			}else{
				// Get the default Session object.
		           Session session = Session.getDefaultInstance(properties,null);
		           
	              // Create a default MimeMessage object.
	              MimeMessage message = new MimeMessage(session);

	              // Set From: header field of the header.
	              message.setFrom(new InternetAddress(mailConfig.getFrom()));

	              // Set To: header field of the header.
	              message.addRecipient(Message.RecipientType.TO,
	                                       new InternetAddress(to));

	              // Set Subject: header field
	              message.setSubject(mailConfig.getSubject(), "UTF-8");

	           // get username in from
	              String[] fromItems = mailConfig.getFrom().split("@");
	              String username=fromItems[0];
	              
	              // Now set the actual message
	              message.setText(mailConfig.getBody()+" Tên tài khoản: "+business.getUserID()+" - Mật khẩu: "+business.getPassWord()+" ", "UTF-8");
				Transport transport = session.getTransport("smtp");
				transport.connect(mailConfig.getSmtpHost(),username, mailConfig.getPassword());
				transport.sendMessage(message, message.getAllRecipients());
				transport.close();
			}
		} catch (Exception e) {
			setErrTimes(errTimes + 1);
			if(errTimes>1){
				log.error("Send mail register business fail for "+business.getCompanyName()+" with mail adress: "+to +" times 2.");
				setErrTimes(0);
				e.printStackTrace();
			}
			else{
				log.error("Send mail register business fail for "+business.getCompanyName()+" with mail adress: "+to +" times 1.");
				e.printStackTrace();
				execute(business.getEmail(), 1);
			}
		}
	}
	@Override
	public Business getModel() {
		// TODO Auto-generated method stub
		return business;
	}
}
